条件分岐 ~ [[ で条件判定(基本)

[[ ~ ]] 論理演算子

条件 説明
EXPRESSION EXPRESSION が true
! EXPRESSION EXPRESSION が false
EXPRESSION1 && EXPRESSION2 EXPRESSION1 と EXPRESSION2 がどちらも true
EXPRESSION1 || EXPRESSION2EXPRESSION1 か EXPRESSION2 のどちらか true
code
echo '評価結果が true の場合は終了ステータスが 0'

[[ ok ]]
echo "[[ ok ]]   : \$?=$?"

[[ '' ]]
echo "[[ '' ]]   : \$?=$?"

[[ ! ok ]]
echo "[[ ! ok ]] : \$?=$?"

[[ ! '' ]]
echo "[[ ! '' ]] : \$?=$?"
stdout
評価結果が true の場合は終了ステータスが 0
[[ ok ]]   : $?=0
[[ '' ]]   : $?=1
[[ ! ok ]] : $?=1
[[ ! '' ]] : $?=0

test コマンドは AND 条件は -a 、OR 条件は -o で記述しますが、複合コマンドの [[ を使用する場合は AND 条件を && 、OR 条件を || で記述します

code
[[ ok && ok ]]
echo "[[ ok && ok ]] : \$?=$?"

[[ ok && '' ]]
echo "[[ ok && '' ]] : \$?=$?"

[[ '' && ok ]]
echo "[[ '' && ok ]] : \$?=$?"

[[ '' && '' ]]
echo "[[ '' && '' ]] : \$?=$?"
stdout
[[ ok && ok ]] : $?=0
[[ ok && '' ]] : $?=1
[[ '' && ok ]] : $?=1
[[ '' && '' ]] : $?=1

&& は 左の結果が false と評価された場合は右を評価しません(短絡評価)

code
# 左の結果が false と評価されるので、右は評価されない
# 標準エラーには L のみが出力される
[[ "$(echo L | tee -a /dev/stderr)" != L && "$(echo R | tee -a /dev/stderr)" ]]
stdout
stderr
L
code
# 左の結果が true と評価されるので、右も実行される
# 標準エラーには L と R が出力される
[[ "$(echo L | tee -a /dev/stderr)" == L && "$(echo R | tee -a /dev/stderr)" ]]
stdout
stderr
L
R
code
[[ ok || ok ]]
echo "[[ ok || ok ]] : \$?=$?"

[[ ok || '' ]]
echo "[[ ok || '' ]] : \$?=$?"

[[ '' || ok ]]
echo "[[ '' || ok ]] : \$?=$?"

[[ '' || '' ]]
echo "[[ '' || '' ]] : \$?=$?"
stdout
[[ ok || ok ]] : $?=0
[[ ok || '' ]] : $?=0
[[ '' || ok ]] : $?=0
[[ '' || '' ]] : $?=1

|| は 左の結果が true と評価された場合は右を評価しません(短絡評価)

code
# 左の結果が true と評価されるので、右は評価されない
# 標準エラーには L のみが出力される
[[ "$(echo L | tee -a /dev/stderr)" == L || "$(echo R | tee -a /dev/stderr)" ]]
stdout
stderr
L
code
# 左の結果が false と評価されるので、右も実行される
# 標準エラーには L と R が出力される
[[ "$(echo L | tee -a /dev/stderr)" != L || "$(echo R | tee -a /dev/stderr)" ]]
stdout
stderr
L
R

[[ ~ ]] 文字列の演算子

条件 説明
-n STRING STRING の文字数が 0 ではない
-z STRING STRING の文字数が 0 である
STRING1 = STRING2 STRING1 と STRING2 が等しい( == と同じ)
STRING1 == STRING2 STRING1 と STRING2 が等しい( = と同じ)
STRING1 != STRING2 STRING1 と STRING2 が等しくない
STRING1 < STRING2 STRING1 が STRING2 より辞書順で前にある
STRING1 > STRING2 STRING1 が STRING2 より辞書順で後にある
code
[[ -n '' ]]
echo "[[ -n '' ]] : \$?=$?"

[[ -n ok ]]
echo "[[ -n ok ]] : \$?=$?"

[[ -z '' ]]
echo "[[ -z '' ]] : \$?=$?"

[[ -z ok ]]
echo "[[ -z ok ]] : \$?=$?"
stdout
[[ -n '' ]] : $?=1
[[ -n ok ]] : $?=0
[[ -z '' ]] : $?=0
[[ -z ok ]] : $?=1
code
[[ '' = '' ]]
echo "[[ '' = '' ]]   : \$?=$?"

[[ '' = ok ]]
echo "[[ '' = ok ]]   : \$?=$?"

[[ '' = 'ok' ]]
echo "[[ '' = 'ok' ]] : \$?=$?"

[[ ok = ok ]]
echo "[[ ok = ok ]]   : \$?=$?"
stdout
[[ '' = '' ]]   : $?=0
[[ '' = ok ]]   : $?=1
[[ '' = 'ok' ]] : $?=1
[[ ok = ok ]]   : $?=0
code
[[ '' == '' ]]
echo "[[ '' == '' ]]   : \$?=$?"

[[ '' == ok ]]
echo "[[ '' == ok ]]   : \$?=$?"

[[ '' == 'ok' ]]
echo "[[ '' == 'ok' ]] : \$?=$?"

[[ ok == ok ]]
echo "[[ ok == ok ]]   : \$?=$?"
stdout
[[ '' == '' ]]   : $?=0
[[ '' == ok ]]   : $?=1
[[ '' == 'ok' ]] : $?=1
[[ ok == ok ]]   : $?=0
code
[[ '' != '' ]]
echo "[[ '' != '' ]]   : \$?=$?"

[[ '' != ok ]]
echo "[[ '' != ok ]]   : \$?=$?"

[[ '' != 'ok' ]]
echo "[[ '' != 'ok' ]] : \$?=$?"

[[ ok != ok ]]
echo "[[ ok != ok ]]   : \$?=$?"
stdout
[[ '' != '' ]]   : $?=1
[[ '' != ok ]]   : $?=0
[[ '' != 'ok' ]] : $?=0
[[ ok != ok ]]   : $?=1

test コマンドの場合は < や > はエスケープする必要がありましたが、複合コマンド [[ の場合はその必要がありません

code
[[ A < B ]]
echo "[[ A < B ]]   : \$?=$?"

[[ B < A ]]
echo "[[ B < A ]]   : \$?=$?"

[[ A < A ]]
echo "[[ A < A ]]   : \$?=$?"

[[ \' < '' ]]
echo "[[ \' < '' ]] : \$?=$?"

[[ \' < A ]]
echo "[[ \' < A ]]  : \$?=$?"
stdout
[[ A < B ]]   : $?=0
[[ B < A ]]   : $?=1
[[ A < A ]]   : $?=1
[[ \' < '' ]] : $?=1
[[ \' < A ]]  : $?=0
code
[[ A > B ]]
echo "[[ A > B ]]   : \$?=$?"

[[ B > A ]]
echo "[[ B > A ]]   : \$?=$?"

[[ A > A ]]
echo "[[ A > A ]]   : \$?=$?"

[[ \' > '' ]]
echo "[[ \' > '' ]] : \$?=$?"

[[ \' > A ]]
echo "[[ \' > A ]]  : \$?=$?"
stdout
[[ A > B ]]   : $?=1
[[ B > A ]]   : $?=0
[[ A > A ]]   : $?=1
[[ \' > '' ]] : $?=0
[[ \' > A ]]  : $?=1

[[ ~ ]] 数値の演算子

複合コマンド [[ でも test コマンドで使用できる数値の演算子が利用できます。

条件 不等号説明
INTEGER1 -eq INTEGER2== INTEGER1 と INTEGER2 が等しい
INTEGER1 -ge INTEGER2>= INTEGER1 は INTEGER2 以上
INTEGER1 -gt INTEGER2> INTEGER1 は INTEGER2 より大きい
INTEGER1 -le INTEGER2<= INTEGER1 は INTEGER2 以下
INTEGER1 -lt INTEGER2< INTEGER1 は INTEGER2 より小さい
INTEGER1 -ne INTEGER2!= INTEGER1 と INTEGER2 は等しくない
code
[[ 1 -eq 1 ]]
echo "[[ 1 -eq 1 ]] : \$?=$?"

[[ 1 -eq 0 ]]
echo "[[ 1 -eq 0 ]]: \$?=$?"
stdout
[[ 1 -eq 1 ]] : $?=0
[[ 1 -eq 0 ]]: $?=1
code
[[ 1 -ge -1 ]]
echo "[[ 1 -ge -1 ]] : \$?=$?"

[[ 1 -ge 0 ]]
echo "[[ 1 -ge  0 ]] : \$?=$?"

[[ 1 -ge 1 ]]
echo "[[ 1 -ge  1 ]] : \$?=$?"

[[ 1 -ge 2 ]]
echo "[[ 1 -ge  2 ]] : \$?=$?"
stdout
[[ 1 -ge -1 ]] : $?=0
[[ 1 -ge  0 ]] : $?=0
[[ 1 -ge  1 ]] : $?=0
[[ 1 -ge  2 ]] : $?=1
code
[[ 1 -gt -1 ]]
echo "[[ 1 -gt -1 ]] : \$?=$?"

[[ 1 -gt 0 ]]
echo "[[ 1 -gt  0 ]] : \$?=$?"

[[ 1 -gt 1 ]]
echo "[[ 1 -gt  1 ]] : \$?=$?"

[[ 1 -gt 2 ]]
echo "[[ 1 -gt  2 ]] : \$?=$?"
stdout
[[ 1 -gt -1 ]] : $?=0
[[ 1 -gt  0 ]] : $?=0
[[ 1 -gt  1 ]] : $?=1
[[ 1 -gt  2 ]] : $?=1
code
[[ 1 -le -1 ]]
echo "[[ 1 -le -1 ]] : \$?=$?"

[[ 1 -le 0 ]]
echo "[[ 1 -le  0 ]] : \$?=$?"

[[ 1 -le 1 ]]
echo "[[ 1 -le  1 ]] : \$?=$?"

[[ 1 -le 2 ]]
echo "[[ 1 -le  2 ]] : \$?=$?"
stdout
[[ 1 -le -1 ]] : $?=1
[[ 1 -le  0 ]] : $?=1
[[ 1 -le  1 ]] : $?=0
[[ 1 -le  2 ]] : $?=0
code
[[ 1 -lt -1 ]]
echo "[[ 1 -lt -1 ]] : \$?=$?"

[[ 1 -lt 0 ]]
echo "[[ 1 -lt  0 ]] : \$?=$?"

[[ 1 -lt 1 ]]
echo "[[ 1 -lt  1 ]] : \$?=$?"

[[ 1 -lt 2 ]]
echo "[[ 1 -lt  2 ]] : \$?=$?"
stdout
[[ 1 -lt -1 ]] : $?=1
[[ 1 -lt  0 ]] : $?=1
[[ 1 -lt  1 ]] : $?=1
[[ 1 -lt  2 ]] : $?=0
code
[[ 1 -ne 1 ]]
echo "[[ 1 -ne 1 ]] : \$?=$?"

[[ 1 -ne 0 ]]
echo "[[ 1 -ne 0 ]] : \$?=$?"
stdout
[[ 1 -ne 1 ]] : $?=1
[[ 1 -ne 0 ]] : $?=0

[[ ~ ]] シェルオプション・シェル変数のチェック

条件 説明
-o OPTNAMEOPTNAME のシェルオプションが有効になっている
-v VARNAMEVARNAME のシェル変数が定義されている
code
set -o noglob +o pipefail
shopt -o | grep -E '^(noglob|pipefail)'
echo '------------------------------'

[[ -o noglob ]]
echo "[[ -o noglob ]]   : \$?=$?"
[[ -o pipefail ]]
echo "[[ -o pipefail ]] : \$?=$?"
stdout
noglob         	on
pipefail       	off
------------------------------
[[ -o noglob ]]   : $?=0
[[ -o pipefail ]] : $?=1
code
var1=

# シェル変数 var1 は定義されているが var2 は定義されていない
[[ -v var1 ]]
echo "[[ -v var1 ]] : \$?=$?"
[[ -v var2 ]]
echo "[[ -v var2 ]] : \$?=$?"
stdout
[[ -v var1 ]] : $?=0
[[ -v var2 ]] : $?=1